#ifndef     __ERROR_H
#define     __ERROR_H

#include <stdint.h>

namespace utils {

namespace ec {

constexpr uint8_t OK = 0;

// CAN发送pkg后没有收到ACK
constexpr uint8_t CAN_NOT_RECV_ACK = 0x01;

// 串口发送后没有收到ACK
constexpr uint8_t RS232_NOT_RECV_ACK = 0x02;

// 无法确定通信接口
constexpr uint8_t CONN_TYPE_FAIL = 0x03;

// 解析参数错误
constexpr uint8_t PARSE_FAIL = 0x04;

// 参数错误
constexpr uint8_t INVALID = 0x05;

// 接收响应超时
constexpr uint8_t RESP_TIMEOUT = 0x06;

// task id 异常
constexpr uint8_t TASK_ID_FAIL = 0x07;

// resp 耗尽
constexpr uint8_t RESP_USE_UP = 0x08;

// SIMPLE resp wait timeout
constexpr uint8_t SIMPLE_RESP_TIMEOUT = 0x09;

// 落杯电机1 堵转
constexpr uint8_t PIPE_LINE_DROP_CUP1_MOTOR_LOCKED = 0x0A;

// 落杯电机1 超时
constexpr uint8_t PIPE_LINE_DROP_CUP1_MOTOR_TIMEOUT = 0x0B;

// 落杯电机2 堵转
constexpr uint8_t PIPE_LINE_DROP_CUP2_MOTOR_LOCKED = 0x0C;

// 落杯电机2 超时
constexpr uint8_t PIPE_LINE_DROP_CUP2_MOTOR_TIMEOUT = 0x0D;

// 落杯1 位置错误
constexpr uint8_t PIPE_LINE_DROP_CUP1_POSITION_ERR = 0x0E;

// 落杯1 失败
constexpr uint8_t PIPE_LINE_DROP_CUP1_FAIL = 0x0F;

// 落杯2 位置错误
constexpr uint8_t PIPE_LINE_DROP_CUP2_POSITION_ERR = 0x10;

// 落杯2 失败
constexpr uint8_t PIPE_LINE_DROP_CUP2_FAIL = 0x11;

// 流水线电机堵转
constexpr uint8_t PIPE_LINE_MOTOR_LOCKED = 0x12;

// 流水线电机超时
constexpr uint8_t PIPE_LINE_MOTOR_TIMEOUT = 0x13;

// 取物门1电机堵转
constexpr uint8_t PICK_DOOR_MOTOR1_LOCKED = 0x14;

// 取物门1电机超时
constexpr uint8_t PICK_DOOR_MOTOR1_TIMEOUT = 0x15;

// 取物门电机1触碰防夹手
constexpr uint8_t PICK_DOOR_MOTOR1_GUARD = 0x16;

// 取物门2电机堵转
constexpr uint8_t PICK_DOOR_MOTOR2_LOCKED = 0x17;

// 取物门2电机超时
constexpr uint8_t PICK_DOOR_MOTOR2_TIMEOUT = 0x18;

// 取物门电机2触碰防夹手
constexpr uint8_t PICK_DOOR_MOTOR2_GUARD = 0x19;

// 吸管盒无法关闭
constexpr uint8_t PICK_STRAW_CLOSE_FAIL = 0x1A;

// 吸管盒无法打开
constexpr uint8_t PICK_STRAW_OPEN_FAIL = 0x1B;

// 取物门1上有东西 无法关闭
constexpr uint8_t PICK_DOOR1_CHECK = 0x1C;

// 取物门2上有东西 无法关闭
constexpr uint8_t PICK_DOOR2_CHECK = 0x1D;

// 取物门1上的东西丢失了
constexpr uint8_t PICK_DOOR1_LOSE = 0x1E;

// 取物门2上的东西丢失了
constexpr uint8_t PICK_DOOR2_LOSE = 0x1F;

// 加热 搅拌盒电机 堵转
constexpr uint8_t HEAT_STIR_BOX_MOTOR_LOCKED = 0x20;

// 加热 搅拌盒电机 超时
constexpr uint8_t HEAT_STIR_BOX_MOTOR_TIMEOUT = 0x21;

// 加热 截热水电机 堵转
constexpr uint8_t HEAT_WATER_MOTOR_LOCKED = 0x22;

// 加热 截热水电机 超时
constexpr uint8_t HEAT_WATER_MOTOR_TIMEOUT = 0x23;

// 加热 截冰电机 堵转
constexpr uint8_t HEAT_ICE_MOTOR_LOCKED = 0x24;

// 加热 截冰电机 超时
constexpr uint8_t HEAT_ICE_MOTOR_TIMEOUT = 0x25;

// Flash
constexpr uint8_t FLASH_CHECK_FAIL = 0x26;
constexpr uint8_t FLASH_ERASE_FAIL = 0x27;
constexpr uint8_t FLASH_WRITE_FAIL = 0x28;

// 加热 蒸汽加热状态异常
constexpr uint8_t HEAT_STEAM_HEAT_INVALID = 0x29;

// 加热 开水加热状态异常
constexpr uint8_t HEAT_WATER_HEAT_INVALID = 0x2A;

// 加热 蒸汽温度传感器异常
constexpr uint8_t HEAT_STEAM_SENSOR_FAIL = 0x2B;

// 加热 开水温度传感器异常
constexpr uint8_t HEAT_WATER_SENSOR_FAIL = 0x2C;

// 加热 蒸汽加热超时
constexpr uint8_t HEAT_STEAM_TIMEOUT = 0x2D;

// 加热 开水加热超时
constexpr uint8_t HEAT_WATER_TIMEOUT = 0x2E;

// 加热 抽水超时
constexpr uint8_t HEAT_DRAW_WATER_TIMEOUT = 0x2F;

// 加热 抽水异常
constexpr uint8_t HEAT_DRAW_WATER_INVALID = 0x30;

// 机械臂 升降电机堵转
constexpr uint8_t ARM_ELEVATOR_MOTOR_LOCKED = 0x31;

// 机械臂 升降电机超时
constexpr uint8_t ARM_ELEVATOR_MOTOR_TIMEOUT = 0x32;

// 机械臂 封膜机 上没有杯子
constexpr uint8_t ARM_FILM_NOT_CUP = 0x33;

// 机械臂 封膜机 状态异常
constexpr uint8_t ARM_FILM_STAUS_INVALID = 0x34;

// 机械臂 封膜机 超时
constexpr uint8_t ARM_FILM_TIMEOUT = 0x35;

// 机械臂 机械臂电机1通信超时
constexpr uint8_t ARM_MOTOR1_CONN_TIMEOUT = 0x36;

// 机械臂 机械臂电机2通信超时
constexpr uint8_t ARM_MOTOR2_CONN_TIMEOUT = 0x37;

// 机械臂 机械臂电机1运动超时
constexpr uint8_t ARM_MOTOR1_RUN_TIMEOUT = 0x38;

// 机械臂 机械臂电机2运动超时
constexpr uint8_t ARM_MOTOR2_RUN_TIMEOUT = 0x39;

// 粉料架 升降超时
constexpr uint8_t POWDER_UPDOWN_MOTOR_TIMEOUT = 0x3A;

// 粉料架 升降堵转
constexpr uint8_t POWDER_UPDOWN_MOTOR_LOCKED = 0x3B;

// 粉料架 倾倒超时
constexpr uint8_t POWDER_DUMP_MOTOR_TIMEOUT = 0x3C;

// 粉料架 倾倒堵转
constexpr uint8_t POWDER_DUMP_MOTOR_LOCKED = 0x3D;

// 粉料架 移动超时
constexpr uint8_t POWDER_MOVE_MOTOR_TIMEOUT = 0x3E;

// 粉料架 移动堵转
constexpr uint8_t POWDER_MOVE_MOTOR_LOCKED = 0x3F;

// 粉料架 货架超时
constexpr uint8_t POWDER_CARGO_MOTOR_TIMEOUT = 0x40;

// 粉料架 货架堵转
constexpr uint8_t POWDER_CARGO_MOTOR_LOCKED = 0x41;

}

struct Error {

public:
    inline Error() : val(ec::OK) {}
    inline Error(uint8_t v) : val(v) {}

    Error(bool) = delete;

    Error& operator=(bool) = delete;

    inline Error& operator=(const Error &other) {
        val = other.val;
        return *this;
    }

    inline Error& operator=(const uint8_t v) {
        val = v;
        return *this;
    }

    inline operator bool() const {
        return val != ec::OK;
    }

    inline bool is_ok() const { return val == ec::OK; }

    inline bool operator==(const Error &other) const {
        return(val == other.val);
    }

    inline bool operator!=(const Error &other) const {
        return (val != other.val);
    }

    inline bool operator!=(uint8_t ec) const {
        return val != ec;
    }
    inline bool operator==(uint8_t ec) const {
        return val == ec;
    }

    uint8_t val;
};


}


#endif
